var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports", "react", "maishu-jueying", "jquery-ui", "../component-panel", "maishu-chitu-react", "maishu-ui-toolkit", "services/local-service", "maishu-chitu", "common", "services/page-datas", "components/menu/component", "component-renders/index", "components/single-colunm-products/shopping-cart-bar", "maishu-ui-toolkit", "json!websiteConfig", "site", "react-dom", "./component-loader"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    const React = require("react");
    const maishu_jueying_1 = require("maishu-jueying");
    require("jquery-ui");
    const component_panel_1 = require("../component-panel");
    const maishu_chitu_react_1 = require("maishu-chitu-react");
    const maishu_ui_toolkit_1 = require("maishu-ui-toolkit");
    const local_service_1 = require("services/local-service");
    const maishu_chitu_1 = require("maishu-chitu");
    const common_1 = require("common");
    const page_datas_1 = require("services/page-datas");
    const component_1 = require("components/menu/component");
    const index_1 = require("component-renders/index");
    const shopping_cart_bar_1 = require("components/single-colunm-products/shopping-cart-bar");
    const ui = require("maishu-ui-toolkit");
    const json_websiteConfig_1 = require("json!websiteConfig");
    const site_1 = require("site");
    const ReactDOM = require("react-dom");
    const component_loader_1 = require("./component-loader");
    requirejs({ context: json_websiteConfig_1.contextName }, ["css!devices"]);
    class MyPageDesigner extends maishu_jueying_1.PageDesigner {
        constructor() {
            super(...arguments);
            this.componentPanel = new maishu_chitu_1.ValueStore();
        }
    }
    exports.MyPageDesigner = MyPageDesigner;
    exports.DesignPageContext = React.createContext({});
    const componentLoaded = "componentLoaded";
    class DesignView extends React.Component {
        constructor(props) {
            super(props);
            this.designer = new maishu_chitu_1.ValueStore();
            this.state = {
                pageData: this.props.pageDataRecord.pageData,
            };
            this.localService = this.props.app.createService(local_service_1.LocalService);
            if (!DesignView.initComponents) {
                DesignView.initComponents = true;
                loadEditors(this.localService);
                loadLessFiles(this.localService);
            }
            this.designer.attach(designer => {
                if (!designer)
                    return;
                //==================================================================================
                // 重写 designer 添加组件方法，在添加组件之前，先加载组件
                let appendComponent = designer.appendComponent;
                designer.appendComponent = (parentId, componentData, componentIndex) => __awaiter(this, void 0, void 0, function* () {
                    yield component_loader_1.ComponentLoader.loadSingleComponent(componentData);
                    appendComponent.apply(designer, [parentId, componentData, componentIndex]);
                });
                //==================================================================================
            });
        }
        customRender(editComponents, items) {
            console.assert(editComponents.length == 1);
            let typename = editComponents[0].type;
            let componentCustomRender = index_1.componentRenders[typename];
            if (!componentCustomRender)
                return null;
            return componentCustomRender(items);
        }
        save() {
            return __awaiter(this, void 0, void 0, function* () {
                let { pageData } = this.state;
                let value = pageData[componentLoaded];
                delete pageData[componentLoaded];
                yield this.localService.savePageDataRecord(this.props.pageDataRecord);
                pageData[componentLoaded] = value;
            });
        }
        setMenu(value) {
            return __awaiter(this, void 0, void 0, function* () {
                let pageData = this._designer.pageData;
                if (value) {
                    let menuComponentData = { type: component_1.Menu.name };
                    page_datas_1.addComponentDataToFooter(pageData, menuComponentData);
                }
                else {
                    page_datas_1.removeComponentDataFromFooter(pageData, component_1.Menu.name);
                }
                this.setState({ pageData });
            });
        }
        setSettleBar(value) {
            return __awaiter(this, void 0, void 0, function* () {
                let pageData = this._designer.pageData;
                if (value) {
                    let componentData = { type: shopping_cart_bar_1.ShoppingCartBar.name };
                    page_datas_1.addComponentDataToFooter(pageData, componentData);
                }
                else {
                    page_datas_1.removeComponentDataFromFooter(pageData, shopping_cart_bar_1.ShoppingCartBar.name);
                }
                this.setState({ pageData });
            });
        }
        hasMenu(pageData) {
            let r = pageData.children.filter(o => o.type == component_1.Menu.name).length > 0;
            return r;
        }
        hasSettleBar(pageData) {
            let r = pageData.children.filter(o => o.type == shopping_cart_bar_1.ShoppingCartBar.name).length > 0;
            return r;
        }
        preivew() {
            let { pageDataRecord } = this.props;
            let pageData = pageDataRecord.pageData;
            console.assert(pageData != null);
            let hasChanged = false;
            if (hasChanged || !pageData.props.id) {
                ui.alert({ title: '提示', message: `预览前必须先保存页面, 请点击"保存"按钮保存页面` });
                return;
            }
            let mobilePath = common_1.stationPath("mobile");
            let url = `${mobilePath}?appKey=${this.localService.applicationId}#page?id=${pageDataRecord.id}`;
            open(url, '_blank');
        }
        // componentWillReceiveProps
        static getDerivedStateFromProps(props) {
            if (props.pageDataRecord == null) {
                return { pageData: page_datas_1.defaultPageDatas.empty() };
            }
            return { pageData: props.pageDataRecord.pageData };
        }
        componentPanelRef(e) {
            return __awaiter(this, void 0, void 0, function* () {
                if (!e || this.componentPanel)
                    return;
                this.componentPanel = e;
                //==========================================================================================
                // 设置组件工具栏
                let componentInfos = yield this.localService.componentInfos(); //getComponentInfos(this.props.app);
                console.assert(componentInfos != null);
                componentInfos = componentInfos.filter(o => o.displayName != null);
                let components = componentInfos.map(o => ({
                    componentData: {
                        type: o.name,
                        props: {
                            attr: { movable: false, container: false, showHandler: false, resize: false }
                        },
                    },
                    displayName: o.displayName,
                    icon: o.icon,
                    introduce: o.introduce
                }));
                this.componentPanel.setComponets(components);
                //==========================================================================================
                console.assert(this._designer != null);
                this.componentPanel.designer = this._designer;
                this._designer.componentPanel.value = this.componentPanel;
            });
        }
        editorPanelRef(e) {
            if (!e || this.editorPanel)
                return;
            this.editorPanel = e;
            this.editorPanel.designer = this._designer;
        }
        render() {
            let { pageData } = this.state;
            if (!pageData[componentLoaded]) {
                component_loader_1.ComponentLoader.loadPageCompontents(pageData)
                    .then(() => {
                    pageData[componentLoaded] = true;
                    this.setState({ pageData });
                })
                    .catch(err => {
                    console.error(err);
                });
                return site_1.default.loadingElement;
            }
            let { hidePageSettingPanel } = this.props;
            return React.createElement(exports.DesignPageContext.Provider, { value: { designPage: this } },
                React.createElement(React.Fragment, null,
                    React.createElement("div", { className: "marvel-device iphone8 black pull-left" },
                        React.createElement("div", { className: "top-bar" }),
                        React.createElement("div", { className: "sleep" }),
                        React.createElement("div", { className: "volume" }),
                        React.createElement("div", { className: "camera" }),
                        React.createElement("div", { className: "sensor" }),
                        React.createElement("div", { className: "speaker" }),
                        React.createElement("article", { className: "screen mobile-page", ref: e => {
                                if (!e)
                                    return;
                                if (!this.designerElement) {
                                    // this.designerElement = document.createElement("div");
                                    // e.appendChild(this.designerElement);
                                    this.designerElement = e;
                                }
                                let page = { element: e, app: this.props.app };
                                ReactDOM.render(React.createElement(maishu_chitu_react_1.PageContext.Provider, { value: { page } },
                                    React.createElement(MyPageDesigner, { pageData: pageData, ref: e => {
                                            if (e == null || this._designer != null)
                                                return;
                                            this._designer = this._designer || e;
                                            this.designer.value = this._designer;
                                        } })), this.designerElement);
                            } }),
                        React.createElement("div", { className: "home" }),
                        React.createElement("div", { className: "bottom-bar" })),
                    React.createElement("div", { style: { marginLeft: 440 } },
                        React.createElement("ul", { style: { height: 32, margin: 0, padding: 0 } },
                            React.createElement("li", { className: "pull-right" },
                                React.createElement("button", { className: "btn btn-sm btn-primary" },
                                    React.createElement("i", { className: "icon-copy" }),
                                    React.createElement("span", null, "\u66F4\u6362\u6A21\u677F")),
                                React.createElement("div", { className: "btn-group" },
                                    React.createElement("button", { className: "btn btn-sm btn-primary dropdown-toggle" },
                                        React.createElement("i", { className: "icon-camera" }),
                                        React.createElement("span", null, "\u5B58\u4E3A\u5FEB\u7167")),
                                    React.createElement("button", { type: "button", className: "btn btn-sm btn-primary dropdown-toggle", "data-toggle": "dropdown", "aria-haspopup": "true", "aria-expanded": "false" },
                                        React.createElement("i", { className: "icon-caret-down" })),
                                    React.createElement("ul", { className: "dropdown-menu" },
                                        React.createElement("li", { style: { padding: "6px 0px" } },
                                            React.createElement("a", { className: "btn-link" },
                                                "\u67E5\u770B\u5FEB\u7167",
                                                React.createElement("span", { className: "badge pull-right" }, "2"))))),
                                React.createElement("button", { className: "btn btn-sm btn-primary", onClick: () => this.preivew() },
                                    React.createElement("i", { className: "icon-eye-open" }),
                                    React.createElement("span", null, "\u9884\u89C8")),
                                React.createElement("button", { className: "btn btn-sm btn-primary", ref: e => {
                                        if (!e)
                                            return;
                                        maishu_ui_toolkit_1.buttonOnClick(e, () => this.save(), { toast: "保存成功!" });
                                    } },
                                    React.createElement("i", { className: "icon-save" }),
                                    React.createElement("span", null, "\u4FDD\u5B58")),
                                React.createElement("button", { className: "btn btn-sm btn-primary", onClick: () => this.props.app.back() },
                                    React.createElement("i", { className: "icon-reply" }),
                                    React.createElement("span", null, "\u8FD4\u56DE"))),
                            React.createElement("li", { className: "" })),
                        React.createElement("hr", { style: { margin: 0, marginTop: -2 } }),
                        React.createElement("div", null,
                            hidePageSettingPanel ? null : React.createElement("div", { className: "pull-right", style: { width: 240 } },
                                React.createElement("div", { className: "panel panel-default" },
                                    React.createElement("div", { className: "panel-heading" }, "\u9875\u9762\u8BBE\u7F6E"),
                                    React.createElement("ul", { className: "list-group" },
                                        React.createElement("li", { className: "list-group-item" },
                                            React.createElement("div", { className: "pull-left", style: { width: "calc(100% - 60px)" } }, "\u663E\u793A\u5BFC\u822A\u83DC\u5355"),
                                            React.createElement("label", { className: "switch" },
                                                React.createElement("input", { type: "checkbox", className: "ace ace-switch ace-switch-5", checked: this.hasMenu(pageData), onChange: e => this.setMenu(e.target.checked) }),
                                                React.createElement("span", { className: "lbl middle" }))),
                                        React.createElement("li", { className: "list-group-item" },
                                            React.createElement("div", { className: "pull-left", style: { width: "calc(100% - 60px)" } }, "\u663E\u793A\u8D2D\u7269\u8F66\u7ED3\u7B97\u680F"),
                                            React.createElement("label", { className: "switch" },
                                                React.createElement("input", { type: "checkbox", className: "ace ace-switch ace-switch-5", checked: this.hasSettleBar(pageData), onChange: e => this.setSettleBar(e.target.checked) }),
                                                React.createElement("span", { className: "lbl middle" })))))),
                            React.createElement("div", { style: { marginRight: hidePageSettingPanel ? null : 260 } },
                                this.props.hideToolbar ? null : React.createElement(React.Fragment, null,
                                    React.createElement("h5", { style: { display: "block" } }, "\u9875\u9762\u7EC4\u4EF6"),
                                    React.createElement(component_panel_1.ComponentPanel, { ref: this.componentPanelRef.bind(this) })),
                                this.props.hideEditorPanel ? null :
                                    React.createElement(maishu_jueying_1.EditorPanel, { ref: this.editorPanelRef.bind(this), className: "well", customRender: (a, b) => this.customRender(a, b) }),
                                this.props.children)))));
        }
    }
    exports.DesignView = DesignView;
    DesignView.initComponents = false;
    function loadEditors(localService) {
        return __awaiter(this, void 0, void 0, function* () {
            let files = yield localService.clientFiles();
            let editorFiles = files.filter(o => o.startsWith("components") && o.endsWith(".js") && o.indexOf("editor") >= 0)
                .map(o => o.substring(0, o.length - ".js".length));
            editorFiles.forEach(path => requirejs({ context: json_websiteConfig_1.contextName }, [path]));
        });
    }
    function loadLessFiles(localService) {
        return __awaiter(this, void 0, void 0, function* () {
            let files = yield localService.clientFiles();
            let editorLessFiles = files.filter(o => o.startsWith("components") && o.endsWith("editor.less"));
            editorLessFiles.forEach(path => {
                common_1.loadLess(path);
            });
        });
    }
});
